# -*- coding: UTF-8 -*-
# Author: Damon(wuud1)
# CreateDate: 
# Message:

from selenium.webdriver.chrome.options import Options
# from selenium.webdriver.firefox.options import Options # 火狐浏览器
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
# from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
import time
import requests
# from untils.yun_da_ma import code_verificate  # 云打码平台
from untils.chaojiying import Chaojiying_Client
from pprint import pprint
# from pyvirtualdisplay import Display
import os
from setting import *
import logging
import redis, json

# 无界面模式
def ChromeDriverNOBrowser(driverPath):
    caps = DesiredCapabilities.CHROME
    caps['loggingPrefs'] = {'performance': 'ALL'}  # 无此设置则拿不到log日志
    chrome_options = Options()
    # chrome_options.add_argument('--no-sandbox')  # 解决DevToolsActivePort文件不存在的报错
    chrome_options.add_argument('--headless')  #浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败
    chrome_options.add_argument('--disable-gpu')  # 谷歌文档提到需要加上这个属性来规避bug
    # chrome_options.add_argument('--hide-scrollbars')  # 隐藏滚动条, 应对一些特殊页面
    # chrome_options.add_argument('blink-settings=imagesEnabled=false')  # 不加载图片, 提升速度
    chrome_options.add_argument('window-size=1920x1080') #指定浏览器分辨率
    # chrome_options.binary_location = r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"  # 手动指定使用的浏览器位置
    driverChrome = webdriver.Chrome(executable_path=driverPath, chrome_options=chrome_options)
    # driverChrome = webdriver.Firefox(executable_path=firefox, firefox_options=chrome_options)  # 火狐浏览器

    return driverChrome

# 有界面
def ChromeDriverBrowser(driverPath):
    caps = DesiredCapabilities.CHROME
    caps['loggingPrefs'] = {'performance': 'ALL'}
    driverChrome = webdriver.Chrome(executable_path=driverPath)
    # driverChrome = webdriver.Firefox(executable_path=firefox)  # 火狐浏览器
    
    driverChrome.set_window_size(1440, 900)
    return driverChrome

class ToolBox:

    def __init__(self, isDisplay=False):
        self.baseUrl = 'https://dp.saic-gm.com'
        self._driverPath = driverPath
        self.errorNum = 0

        # 云打码信息
        # self._ydm_user = ydm_username
        # self._ydm_pswd = ydm_password
        # self._ydm_appId = ydm_appId
        # self._ydm_appKey = ydm_appKey



        self.isDisplay = isDisplay
        if self.isDisplay:
            self.browser = ChromeDriverBrowser(self._driverPath)
        else:
            self.browser = ChromeDriverNOBrowser(self._driverPath)
        self.wait = WebDriverWait(self.browser, 30)
        # self.r = redis.Redis(**redis_config)

    def __del__(self):
        try:
            self.browser.close()
            self.browser.switch_to_window(self.browser.window_handles[0])
            self.browser.close()
            self.browser.quit()
            os.system('pkill -f chromedriver')
        except:
            pass

    def get_verifyCodeImg2local(self):
        imgVeri = self.wait.until(EC.presence_of_element_located((By.XPATH, '//img[@id="verifyCode"]')))
        verifyUrl = imgVeri.get_attribute('src')
        currentJSESSIONID = self.browser.get_cookie("JSESSIONID").get("value")
        currentTimeStr = str(time.time())[:10]
        currentUrl = self.browser.current_url
        # 组装请求图片的cookies
        imgCookies = {
            "GUEST_LANGUAGE_ID": "zh_CN",
            "COOKIE_SUPPORT": "true",
            "LFR_SESSION_STATE_279147": currentTimeStr,
            "JSESSIONID": currentJSESSIONID,
        }
        imgHeaders = {
            # 尽量统一ua
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
            "Referer": currentUrl
        }
        # print(imgCookies)
        # print(imgHeaders)
        try:
            _res = requests.get(url=verifyUrl, headers=imgHeaders, cookies=imgCookies, timeout=30)
        except:
            try:
                _res = requests.get(url=verifyUrl, headers=imgHeaders, cookies=imgCookies, timeout=30)
            except Exception as e:
                print(e.__repr__())
                return False
        with open(verifyCodeName, 'wb') as v:
            v.write(_res.content)
        return True


    def get_verifyCode(self):
        # 获取验证码结果
        # 获取验证码url并获取图片到本地
        _res = self.get_verifyCodeImg2local()
        if not _res:
            _res = self.get_verifyCodeImg2local()

        # 请求超级鹰打码平台
        # 超级鹰打码平台
        chaojiying = Chaojiying_Client('peipeiyun', '1qaz@WSX', '96001')
        im = open(verifyCodeName, 'rb').read()
        valid_obj = chaojiying.PostPic(im, 1902)
        verifyCode = valid_obj['pic_str']

        # # 请求云打码获取验证码数字
        # fileName = verifyCodeName
        # rs = code_verificate(fileName, self._ydm_user, self._ydm_pswd, self._ydm_appId, self._ydm_appKey, code_type=1006)
        # verifyCode = rs[0]
        return verifyCode

    def _input(self):
        '''输入登录信息, 返回登录结果'''
        iptUser = self.wait.until(EC.presence_of_element_located((By.XPATH, '//input[@placeholder="用户名"]')))
        iptPawd = self.wait.until(EC.presence_of_element_located((By.XPATH, '//input[@placeholder="密码"]')))
        iptVeri = self.wait.until(EC.presence_of_element_located((By.XPATH, '//input[@placeholder="验证码"]')))
        iptSubmit = self.wait.until(
            EC.presence_of_element_located((By.XPATH, '//input[contains(@class, "easyui-linkbutton")]')))
        # 输入用户名密码
        iptUser.clear()
        iptUser.send_keys(self._userName)
        iptPawd.clear()
        iptPawd.send_keys(self._password)
        # 获取验证码url
        verifyCode = self.get_verifyCode()
        iptVeri.clear()
        iptVeri.send_keys(verifyCode)
        iptSubmit.click()
        # 判断是否登录成功
        loginResult = self.isLogin()
        if loginResult == 0:  # 验证码错误, 递归处理
            self.errorNum += 1
            print("验证码错误, 重试第{}次".format(self.errorNum))
            if self.errorNum == verifyCode_errortimes:
                self.errorNum = 0
                return loginResult
            return self._input()
        return loginResult

    def handleCookies(self, currenCookies):
        _dict = {}
        c_l = []
        for info in currenCookies:
            name = info.get("name", "")
            value = info.get("value", "")
            _dict[name] = value
            s = "{}={}".format(name, value)
            c_l.append(s)
        return "; ".join(c_l), _dict

    def _getCookies(self):
        time.sleep(1)
        try:
            a_intoIndex = self.wait.until(EC.presence_of_element_located((By.XPATH, '//div[@class="passExpNoti_bt02"]/a')))
            a_intoIndex.click()
        except:
            pass
        self.browser.switch_to_frame(2) # 切换到相应的iframe
        a_saicgmPartCatalog = self.wait.until(EC.presence_of_element_located((By.XPATH, '//a[contains(text(), "上汽通用配件工程目录浏览系统")]')))
        # print(a_saicgmPartCatalog.text)
        a_saicgmPartCatalog.click()
        time.sleep(1)
        self.browser.switch_to_window(self.browser.window_handles[1])  # 切换到对应标签页
        select_kdlk = self.wait.until(EC.presence_of_element_located((By.XPATH, '//select[@id="brandsSelect"]/option[1]')))
        select_kdlk.click()  # 点击凯迪拉克品牌
        option_ALL = self.wait.until(EC.presence_of_element_located((By.XPATH, '//option[@value="ALL"]')))
        option_ALL.click()
        time.sleep(1)
        currenCookies = self.browser.get_cookies()
        cookiesStr, cookiesDict = self.handleCookies(currenCookies)
        # _log = self.browser.get_log('performance')
        # with open('./chromedriver.log', 'w') as l:
        #     l.write(json.dumps(_log, ensure_ascii=False, indent=4))
        return cookiesStr, cookiesDict

    def getCookies(self):
        # 获取登录界面
        # self.browser.set_page_load_timeout(3)
        self.browser.get(self.baseUrl)
        # 输入登录信息, 接收登录结果
        loginResult = self._input()
        # 根据登录结果进行相关处理
        if loginResult == 1:  # 登录成功
            print("登录成功: ", self._userName)
            cookiesStr, cookiesDict = self._getCookies()
            currentUrl = self.browser.current_url
            return cookiesStr, cookiesDict, currentUrl
            # print(cookies)
            # self.r.set(self.redis_key, cookies)
            # self.r.set(self.redis_key_ttl, "3*60*60")
            # self.r.expire(self.redis_key_ttl, 3*60*60)
            # self.r.set(self.redis_key_valid, "valid")
            # self.r.expire(self.redis_key_valid, 7200)
        elif loginResult == 0:  # 验证码错误三次
            pass
        elif loginResult == -1:  # 用户名或密码错误
            pass

    def isLogin(self):
        '''1: 登录成功
            0: 验证码错误
            -1: 账号密码错误'''
        time.sleep(1)
        try:
            div_redText = self.browser.find_element_by_xpath('//div[@class="redtext"]')  # 如果定位元素失败,则登录成功
            errorMessage = div_redText.text
            # print(errorMessage)
            if "验证码" in errorMessage:
                loginRes = 0
            elif ("密码" in errorMessage) or ("用户名" in errorMessage) or ("账号" in errorMessage):
                loginRes = -1
        except:
            loginRes = 1

        return loginRes

    def checkCookie(self, cookiestr):
        """检查cookie是否有效"""
        headers = {
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
            "Cookie": cookiestr
        }
        person_url = 'http://dp.saic-gm.com/dp/web/guest/personcenter'
        res = requests.get(person_url,headers=headers,allow_redirects=False)
        if res.status_code == 302:
            return False, 1
        return True, 2

    #def run(self, ctype, username, password):
    def run(self, username, password):
        self._userName = username
        self._password = password
        # 根据ctype+username 获取本地的cookies并检测是否有效
        # self.redis_key = ctype.lower()+'_'+username.lower()+'_'+'cookie'
        # self.redis_key_ttl = ctype.lower()+'_'+username.lower()+'_'+'ttl'
        # self.redis_key_valid = ctype.lower()+'_'+username.lower()+'_'+'valid_cookie'
        # cookiestr = self.r.get(self.redis_key)
        cookiestr = None
        if cookiestr:
            res, code = self.checkCookie(cookiestr)
        else:
            res = False
        if not res:
            try:
                return self.getCookies()
            except Exception as e:
                # logging.error(e.__repr__())
                print(e.__repr__())

# def main():
#     for ctype in Account:
#         info_l = Account.get(ctype)
#         for info in info_l:
#             username = info.get("username")
#             password = info.get("password")
#             # print(username, password)
#
#             tools = ToolBox(isDisplay=True)
#             tools.run(ctype, username, password)
#
# if __name__ == '__main__':
#     main()
